package com.dnjn.mes.biz.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.dnjn.mes.biz.assist.WorkforceTaskHandler;
import com.dnjn.mes.biz.assist.ext.Wrapperz;
import com.dnjn.mes.biz.domain.*;
import com.dnjn.mes.biz.enums.BoolType;
import com.dnjn.mes.biz.service.*;
import com.dnjn.mes.biz.service.helper.WorkShiftHelper;
import com.dnjn.mes.common.core.controller.BaseController;
import com.dnjn.mes.common.core.domain.AjaxResult;
import com.dnjn.mes.common.core.domain.R;
import com.dnjn.mes.common.utils.StringUtils;
import com.google.common.collect.Maps;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 开放首页/open开头请求controller 前端控制器
 * </p>
 */
@RestController
@RequestMapping("/open/biz")
public class OpenBizController extends BaseController {
    @Autowired
    private IMesRecordCapacityService recordCapacityService;

    @Autowired
    private IMesEquipmentService equipmentService;

    @Autowired
    private IMesRecordExceptService recordExceptService;

    @Autowired
    protected IMesEquipmentService iMesEquipmentService;

    @Autowired
    protected IMesAssemblyService assemblyService;

    @Autowired
    protected IMesWorkpieceService workpieceService;

    @Autowired
    protected IMesRecordBeatService recordBeatService;

    @Autowired
    protected IMesMessageService messageService;

    @Autowired
    private IMesWorkforceConfigService mesWorkforceConfigService;

    @Autowired
    protected IMesWorkforceShiftService shiftService;

    @Autowired
    private WorkShiftHelper workShiftHelper;

    @Autowired
    private IMesWorkforceShiftClockingService clockingService;

    @Autowired
    private WorkforceTaskHandler workforceTaskHandler;

    @Operation(summary = "获取当前机器信息")
    @GetMapping("/currentEquipment")
    public AjaxResult current() {
        return success(equipmentService.getOne(
                Wrapperz.lambdaQuery(MesEquipment.class).eq(MesEquipment::getIsDefault, BoolType.YES)));
    }


    /**
     * 稼动率
     */
    @Operation(summary = "获取稼动率")
    @PostMapping("/getUtilizationRate")
    public R<Integer> getUtilizationRate(@RequestHeader(value = "equipmentId") long equipmentId) {
        MesEquipment mesEquipment = equipmentService.getOne(Wrapperz.lambdaQuery(MesEquipment.class).eq(MesEquipment::getIsDefault, BoolType.YES));
        if (mesEquipment == null) {
            return R.fail();
        }
        Integer defaultBeat = mesEquipment.getDefaultBeat();
        if (Objects.isNull(defaultBeat)) {
            //return error("默认节拍为空");
            return R.fail("默认节拍为空");
        }
        Integer utilizationRate = recordCapacityService.getUtilizationRate(defaultBeat, equipmentId);
        utilizationRate = utilizationRate > 100 ? 100 : utilizationRate;
        return R.ok(utilizationRate);
    }

    /**
     * 当天故障次数
     */
    @Operation(summary = "当天故障次数")
    @GetMapping("/countRecords")
    public AjaxResult countRecords(@RequestHeader(value = "equipmentId") long equipmentId) {
        Integer count = recordExceptService.countRecords(equipmentId);
        return success(count);
    }

    /**
     * 获取当天总产能
     */
    /*@Operation(summary ="获取当天总产能")
    @PostMapping("/sumTodayRecordCapacity")
    public AjaxResult sumTodayRecordCapacity(@RequestHeader( value="equipmentId") long equipmentId ) {
        int sum  = recordCapacityService.sumTodayRecordCapacity(equipmentId);
        if(Objects.isNull(sum)){
            return success(0);
        }
        return success(sum);
    }*/

    /**
     * 获取早班当天早班总产能 早八点-晚八点
     */
    /*@Operation(summary ="获取早班产能")
    @PostMapping("/sumEarlyRecordCapacity")
    public AjaxResult sumEarlyRecordCapacity(@RequestHeader( value="equipmentId") long equipmentId) {
        List<MesRecordCapacity> list = recordCapacityService.getEarlyRecordCapacityChart(equipmentId);
        if(list.isEmpty()){
            return success(0);
        }
        int sum = list.stream().filter(m -> !Objects.isNull(m.getCapacity())).mapToInt(MesRecordCapacity::getCapacity).sum();
        return success(sum);
    }*/

    /**
     * 获取当天晚班总产能 晚八点 - 早八点
     */
    /*@Operation(summary ="获取晚班产能")
    @PostMapping("/sumNightRecordCapacity")
    public AjaxResult sumNightRecordCapacity(@RequestHeader( value="equipmentId") long equipmentId) {
        List<MesRecordCapacity> list = recordCapacityService.getNightRecordCapacityChart(equipmentId);
        if(list.isEmpty()){
            return success(0);
        }
        int sum = list.stream().filter(m -> !Objects.isNull(m.getCapacity())).mapToInt(MesRecordCapacity::getCapacity).sum();
        return success(sum);
    }*/

    /**
     * 故障信息栏
     */
    @Operation(summary = "故障信息栏列表")
    @PostMapping("/getRecordExceptList")
    public AjaxResult getRecordExceptList(@RequestHeader(value = "equipmentId") long equipmentId) {
        //按照故障时间倒叙
        List<MesRecordExcept> list = recordExceptService.getRecordExceptList(equipmentId);
        return success(list);
    }

    /**
     * 设备运行状态时间统计模块
     */
    @Operation(summary = "设备运行状态时间统计模块 ")
    @PostMapping("/countStatusTime")
    public AjaxResult countStatusTime(@RequestHeader(value = "equipmentId") long equipmentId) {
        ArrayList<RunStatus> list = iMesEquipmentService.countStatusTime(equipmentId);
        return success(list);
    }

    /**
     * 获取模块列表，并根据是否有需要保养的零部件进行警告提醒排序
     */

    @Operation(summary = "获取模块列表")
    @PostMapping("/searchAssemblyList/{equipmentId}")
    public AjaxResult searchAssemblyList(@PathVariable long equipmentId) {
        Assert.notNull(equipmentId, "equipmentId不能为空！");
        List<MesAssembly> list = assemblyService.searchAssemblyList(equipmentId);
        if (list.isEmpty()) {
            return success("模块列表为空！");
        }
        Collections.sort(list, new Comparator<MesAssembly>() {
            @Override
            public int compare(MesAssembly o1, MesAssembly o2) {
                return o1.getStatus() - o2.getStatus();
            }
        });
        return success(list);
    }


    /**
     * 首页维护保养倒计时-查询零部件保养寿命最近的
     */
    @Operation(summary = "首页维护保养倒计时")
    @GetMapping("/maintenanceCountdown")
    public AjaxResult maintenanceCountdown(@RequestHeader(value = "equipmentId") long equipmentId) {
        MesWorkpiece mesWorkpiece = workpieceService.maintenanceCountdown(equipmentId);
        logger.info("首页维护保养倒计时" + mesWorkpiece);
        return success(mesWorkpiece);
    }

    /**
     * 获取早班产能折线图 早八点-晚八点
     */
   /* @Operation(summary ="获取早班产能折线图")
    @PostMapping("/getEarlyRecordCapacityChart")
    public AjaxResult getEarlyRecordCapacityChart(@RequestHeader( value="equipmentId") long equipmentId) {
        List<MesRecordCapacity> list = recordCapacityService.getEarlyRecordCapacityChart(equipmentId);
        return success(list);
    }*/


    /**
     * 获取晚班产能折线图 晚八点 - 早八点
     */
    /*@Operation(summary ="获取晚班产能折线图")
    @PostMapping("/getNightRecordCapacityChart")
    public AjaxResult getNightRecordCapacityChart(@RequestHeader( value="equipmentId") long equipmentId) {
        List<MesRecordCapacity> list = recordCapacityService.getNightRecordCapacityChart(equipmentId);
        return success(list);
    }*/


    /**
     * 获取早班节拍图 早八点-晚八点
     */
   /* @Operation(summary ="获取早班节拍图")
    @PostMapping("/getEarlyRecordBeatChart")
    public AjaxResult getEarlyRecordBeatChart(@RequestHeader( value="equipmentId") long equipmentId) {
        List<MesRecordBeat> list = recordBeatService.getEarlyRecordBeatChart(equipmentId);
        return success(list);
    }*/

    /**
     * 获取早班节拍图 晚八点- 早八点
     */
   /* @Operation(summary ="获取晚班节拍图")
    @PostMapping("/getNightRecordBeatChart")
    public AjaxResult getNightRecordBeatChart(@RequestHeader( value="equipmentId") long equipmentId) {
        List<MesRecordBeat> list = recordBeatService.getNightRecordBeatChart(equipmentId);
        return success(list);
    }*/


    /**
     * 二级页面获取工件零部件列表根据模块id，以及名称模糊搜索,根据首字母排序-升序
     */
    @Operation(summary = "二级页面获取工件零部件列表")
    @PostMapping("/searchWorkByName")
    public AjaxResult searchWorkByName(@RequestParam(required = false) @Parameter(description = "workpieceName") String searchKey,
                                       @RequestParam long assemblyId) {
        ArrayList<MesWorkpiece> list = (ArrayList<MesWorkpiece>) workpieceService.searchWorkByName(searchKey, assemblyId);
        if (list.isEmpty()) {
            return success("零部件列表为空！");
        }
        Collections.sort(list, new Comparator<MesWorkpiece>() {
            @Override
            public int compare(MesWorkpiece o1, MesWorkpiece o2) {
                return o1.getStatus() - o2.getStatus();
            }
        });
        return success(list);
    }


    /**
     * 设备分析栏
     */
    @Operation(summary = "设备分析栏")
    @PostMapping("/equipmentAnalysis")
    public AjaxResult equipmentAnalysis(@RequestHeader(value = "equipmentId") long equipmentId) {
        QueryWrapper<MesMessage> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("message_status", "1");
        queryWrapper.eq("equipment_id", equipmentId);
        queryWrapper.orderByDesc("create_time");
        List<MesMessage> list = messageService.list(queryWrapper);
        return success(list);
    }

    /**
     * 动态获取当天总产能
     */
    @Operation(summary = "动态获取当天总产能")
    @PostMapping("/sumTodayTrendsRecordCapacity")
    public AjaxResult sumTodayRecordCapacity(@RequestHeader(value = "equipmentId") long equipmentId) {
        //int sum  = recordCapacityService.sumTodayRecordCapacity(equipmentId);
        List<MesWorkforceConfig> workforceConfigList = mesWorkforceConfigService.getTrendsRecordCapacityCount(equipmentId);
        if (null == workforceConfigList) {
            return error("请检查班次");
        }
        int sum = 0;
        for (MesWorkforceConfig mesWorkforceConfig : workforceConfigList) {
            Integer totalCapacity = mesWorkforceConfig.getTotalCapacity();
            sum += totalCapacity;
        }
        return success(sum);
    }


    /**
     * 动态获取各个班次总产量
     */
    @Operation(summary = "动态获取各个班次总产量")
    @PostMapping("/getTrendsRecordCapacityCount")
    public AjaxResult getTrendsRecordCapacityCount(@RequestHeader(value = "equipmentId") long equipmentId) {
        List<MesWorkforceConfig> workforceConfigList = mesWorkforceConfigService.getTrendsRecordCapacityCount(equipmentId);
        return success(workforceConfigList);
    }

    /**
     * 动态获取产能各个班次产量
     */
    @Operation(summary = "动态获取产能各个班次产量")
    @PostMapping("/getTrendsRecordCapacity")
    public AjaxResult getTrendsRecordCapacity(@RequestHeader(value = "equipmentId") long equipmentId) throws Exception {
        List<MesWorkforceConfig> workforceConfigList = mesWorkforceConfigService.getTrendsRecordCapacity(equipmentId);
        return success(workforceConfigList);
    }


    /**
     * 动态获取节拍各个班次节拍
     */
    @Operation(summary = "动态获取节拍各个班次节拍")
    @PostMapping("/getTrendsRecordBeatChart")
    public AjaxResult getTrendsRecordBeatChart(@RequestHeader(value = "equipmentId") long equipmentId) {
        //List<MesWorkforceConfig> list = mesWorkforceConfigService.getTrendsRecordBeatChart(equipmentId);
        List<MesRecordBeat> list = mesWorkforceConfigService.getIndexRecordBeatChart(equipmentId);
        return success(list);
    }


    /**
     * 获取当前班次信息
     */
    @Operation(summary = "获取当前班次信息")
    @GetMapping("/getNowWorkforces")
    public AjaxResult getNowWorkforces() {
        MesEquipment mesEquipment = equipmentService.fetchCurrent();
        if (null == mesEquipment) {
            return error("当前设备为空");
        }
        Long equipmentId = mesEquipment.getEquipmentId();
        WorkShiftHelper.WorkShiftConf helper = workShiftHelper.current();
        MesWorkforceConfig before = helper.getBefore();
        MesWorkforceConfig current = helper.getCurrent();
        MesWorkforceConfig after = helper.getAfter();
        LocalDate currentDate = LocalDateTime.now().minusHours(8).toLocalDate();
        MesWorkforceShift curShift = null, afterShift = null, beforeShift = null;
        curShift = getShift(current, currentDate, equipmentId);

        //如果存在当前班次，却不存在当前班次记录和用户列表,说明定时器没有提前将班次信息写入班次记录，手动插入一遍班次记录和人员列表
        if (null != current && null == curShift) {
            //将当前班次写入班次记录表
            workforceTaskHandler.handleWorkforceshift(current.getStartTime().toString(),equipmentId.toString());
            curShift = getShift(current, currentDate, equipmentId);
        }
        LocalTime now = LocalTime.now();
        if (null != after) {
            if (now.compareTo(after.getStartTime().minusMinutes(20)) >= 0 && now.isBefore(after.getStartTime())) {
                afterShift = getShift(after, currentDate, equipmentId);
            }
        }
        if (null != before) {
            if (now.isAfter(before.getEndTime()) && now.compareTo(before.getEndTime().plusMinutes(20)) <= 0) {
                //如果是即将下班的班次，查询deleted为0的shift记录。如果为1 就是已经全部下班了 不需要展示
                beforeShift = checkWorkOutAll(equipmentId, before, currentDate);
//                beforeShift = getShift(before, currentDate, equipmentId);
            }
        }
        Map rv = Maps.newHashMap();
        rv.put("current", curShift);
        rv.put("after", afterShift);
        rv.put("before", beforeShift);
        return success(rv);
    }

    private MesWorkforceShift checkWorkOutAll(Long equipmentId, MesWorkforceConfig after, LocalDate currentDate) {
        MesWorkforceShift shift = shiftService.lambdaQuery().eq(MesWorkforceShift::getWorkforceId, after.getWorkforceId())
                .eq(MesWorkforceShift::getCurrentDate, currentDate).eq(MesWorkforceShift::getEquipmentId, equipmentId).one();
        if (null == shift) {
            return null;
        }
        List<MesWorkforceShiftClocking> clockingList = clockingService.lambdaQuery().eq(MesWorkforceShiftClocking::getShiftId, shift.getShiftId()).list();
        if (null != clockingList && clockingList.size() > 0) {
            Boolean flag = true;
            for (MesWorkforceShiftClocking clocking : clockingList) {
                if ("0".equals(clocking.getHasClockout())) {
                    //如果有打卡用户没下班打卡就显示上一班次信息
                    flag = false;
                }
            }
            shift.setClockingList(clockingList);
            if (flag) {//true->上一班次全部下班打卡 不需要展示
                return null;
            }
        }
        return shift;
    }

    private MesWorkforceShift getShift(MesWorkforceConfig current, LocalDate currentDate, Long equipmentId) {
        if (null == current) {
            return null;
        }
        MesWorkforceShift shift = shiftService.lambdaQuery().eq(MesWorkforceShift::getWorkforceId, current.getWorkforceId())
                .eq(MesWorkforceShift::getCurrentDate, currentDate).eq(MesWorkforceShift::getEquipmentId, equipmentId).one();
        if (null == shift) {
            return null;
        }
        List<MesWorkforceShiftClocking> clockingList = clockingService.lambdaQuery().eq(MesWorkforceShiftClocking::getShiftId, shift.getShiftId()).list();
        shift.setClockingList(clockingList);
        return shift;
    }

}

